using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.IO;
using System.Diagnostics;
using System.Reflection;

namespace TemplatesManager
{
	public enum Languages
	{
		CS,
		VB,
		WEBCS,
		WEBVB
	}

	class ItemManager
	{
		private RegistryKey _rk;
		private string _vsVersion;

		public ItemManager(string vsVersion)
		{
			_vsVersion = vsVersion;
		}

        public void ExecuteDevEnvSetup()
        {
            InitializeVSKey();

            _rk = _rk.OpenSubKey(_vsVersion).OpenSubKey("Setup").OpenSubKey("VS");

            string devenv = (string)_rk.GetValue(@"EnvironmentPath");

            ProcessStartInfo startInfo = new ProcessStartInfo(devenv, "/setup");
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;

            //Process.Start(startInfo);

            Process proc = new Process();
            proc.StartInfo = startInfo;
            proc.Start();
            proc.WaitForExit();
        }

        public void RegisterTemplates()
        {
            InitializeVSKey();

            _rk = _rk.OpenSubKey(_vsVersion).OpenSubKey("Setup").OpenSubKey("VS");

            string devenv = (string)_rk.GetValue(@"EnvironmentPath");

            ProcessStartInfo startInfo = new ProcessStartInfo(devenv, "/installvstemplates");
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;

            Process proc = new Process();
            proc.StartInfo = startInfo;
            proc.Start();
            proc.WaitForExit();
        }

        /// <summary>
        /// Creates the euss var32 BATCH file.
        /// </summary>
        public void CreateEussVars(string eussInstallDir)
        {
            string filename = Path.Combine(eussInstallDir, "eussvar32.bat");
            DeleteEussVars(eussInstallDir);
            StreamWriter sw = File.CreateText(filename);
            sw.WriteLine(String.Concat("%comspec% /K \"@SET PATH=", eussInstallDir, ";%PATH%" ));
            sw.Close();
        }

        public void DeleteEussVars(string eussInstallDir)
        {
            string filename = Path.Combine(eussInstallDir, "eussvar32.bat");
            if (File.Exists(filename))
                File.Delete(filename);
        }

        public void InstallTemplateFile(Languages lang, string customeDir, string ressourceName, string fileName)
		{
			string destTemplatesDir = GetItemTemplatesDir(lang);

			if (destTemplatesDir == String.Empty)
				throw new Exception("Cannot find the VS templates directory");

			string customTemplatesDir = destTemplatesDir + @"\" + customeDir + @"\";

			if (!Directory.Exists(customTemplatesDir))
				Directory.CreateDirectory(customTemplatesDir);

			ExtractResource(ressourceName, String.Concat(customTemplatesDir + @"\", fileName));
		}

		public void InstallShemaFile(string ressourceName, string fileName)
		{
			string destSchemasDir = String.Empty;
			if (_vsVersion == "7.1")
				destSchemasDir = GetShemasDir("VS7CommonDir");
			if (_vsVersion == "8.0")
				destSchemasDir = GetShemasDir("ProductDir");

			if (destSchemasDir == String.Empty)
				throw new Exception("Cannot find your VS schemas directory");

			ExtractResource(ressourceName, String.Concat(destSchemasDir, fileName));
		}

		public void DeleteTemplateFile(Languages lang, string customDir, string fileName)
		{
			string destTemplatesDir = GetItemTemplatesDir(lang);

			if (destTemplatesDir == String.Empty)
				throw new Exception("Cannot find your VS template directory");

			string eussTemplatesDir = destTemplatesDir + @"\" + customDir + @"\";

			if (File.Exists(String.Concat(eussTemplatesDir, fileName)))
				File.Delete(String.Concat(eussTemplatesDir, fileName));
		}

		public void DeleteTemplateDir(Languages lang, string eussDir)
		{
			string destTemplatesDir = GetItemTemplatesDir(lang);

			if (destTemplatesDir == String.Empty)
				throw new Exception("Cannot find your VS template directory");

			string eussTemplatesDir = destTemplatesDir + @"\" + eussDir + @"\";

			if (Directory.Exists(eussTemplatesDir))
				Directory.Delete(eussTemplatesDir);
		}

		public void DeleteShemaFile(string fileName)
		{
			string destSchemasDir = String.Empty;
			if (_vsVersion == "8.0")
				destSchemasDir = GetShemasDir("ProductDir");
			if (_vsVersion == "7.1")
				destSchemasDir = GetShemasDir("VS7CommonDir");

			if (destSchemasDir == String.Empty)
				throw new Exception("Cannot find your VS schema directory");

			if (File.Exists(String.Concat(destSchemasDir, fileName)))
				File.Delete(String.Concat(destSchemasDir, fileName));
		}

		private void ExtractResource(string resource, string filename)
		{
			Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);

			BinaryReader br = new BinaryReader(s);
			Byte[] buff = new Byte[s.Length];
			buff = br.ReadBytes(buff.Length);
			br.Close();

			BinaryWriter bw = new BinaryWriter(new FileStream(filename, FileMode.Create, FileAccess.Write));
			bw.Write(buff);
			bw.Close();
		}

		private RegistryKey InitializeVSKey()
		{
			_rk = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("VisualStudio");
			if (_rk != null)
			{
				return _rk;
			}

			_rk = Registry.CurrentUser.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("VisualStudio");
			if (_rk != null)
			{
				return _rk;
			}

			throw new Exception("Cannot find Visual Studio");
		}

		private string GetShemasDir(string vsCommonDir)
		{
			InitializeVSKey();

			_rk = _rk.OpenSubKey(_vsVersion).OpenSubKey("Setup").OpenSubKey("VS");

			string commonDir = (string)_rk.GetValue(@vsCommonDir);

			if (_vsVersion == "7.1")
				return String.Concat(commonDir, @"\Packages\schemas\xml\");
			if (_vsVersion == "8.0")
				return String.Concat(commonDir, @"\Xml\Schemas\");

			return String.Empty;
		}

		private string GetWizardsTemplatesDir(Languages lang)
		{
			InitializeVSKey();

			_rk = _rk.OpenSubKey(_vsVersion).OpenSubKey("Projects");

			if (lang == Languages.CS)
				return (string)_rk.OpenSubKey(VSLangProj.PrjKind.prjKindCSharpProject).GetValue(@"WizardsTemplatesDir");
			if (lang == Languages.VB)
				return (string)_rk.OpenSubKey(VSLangProj.PrjKind.prjKindVBProject).GetValue(@"WizardsTemplatesDir");

			return String.Empty;
		}

		private string GetItemTemplatesDir(Languages lang)
		{
			InitializeVSKey();

			if (_vsVersion == "7.1")
			{
				_rk = _rk.OpenSubKey(_vsVersion).OpenSubKey("Projects");

				if (lang == Languages.CS)
					return (string)_rk.OpenSubKey(VSLangProj.PrjKind.prjKindCSharpProject).GetValue(@"ItemTemplatesDir") + @"\";
				if (lang == Languages.VB)
					return (string)_rk.OpenSubKey(VSLangProj.PrjKind.prjKindVBProject).GetValue(@"ItemTemplatesDir") + @"\";
			}

			if (_vsVersion == "8.0")
			{
				string langTemplateName = String.Empty;
				string commonItemTemplatesDir = (string)_rk.OpenSubKey(_vsVersion).OpenSubKey("VSTemplate").OpenSubKey("Item").GetValue(@"UserFolder");

				InitializeVSKey();

				_rk = _rk.OpenSubKey(_vsVersion).OpenSubKey("Projects");

				if (lang == Languages.CS)
					langTemplateName = (string)_rk.OpenSubKey(VSLangProj.PrjKind.prjKindCSharpProject).GetValue(@"Language(VsTemplate)") + "\\";
				if (lang == Languages.VB)
					langTemplateName = (string)_rk.OpenSubKey(VSLangProj.PrjKind.prjKindVBProject).GetValue(@"Language(VsTemplate)") + "\\";
				if (lang == Languages.WEBCS)
					langTemplateName = (string)_rk.OpenSubKey(VsWebSite.PrjKind.prjKindVenusProject).GetValue(@"Language(VsTemplate)") + "\\CSharp\\";
				if (lang == Languages.WEBVB)
					langTemplateName = (string)_rk.OpenSubKey(VsWebSite.PrjKind.prjKindVenusProject).GetValue(@"Language(VsTemplate)") + "\\VisualBasic\\";

				return String.Concat(commonItemTemplatesDir, "\\", langTemplateName);
			}

			return String.Empty;
		}
	}
}
